package org.dreamwork.sso.saml2.listener;

import org.dreamwork.sso.saml2.SamlKeys;
import org.dreamwork.sso.saml2.spec.IKeyFetcher;
import org.dreamwork.sso.saml2.spec.KeyFetcherFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dreamwork.util.StringUtil;
import org.opensaml.DefaultBootstrap;
import org.opensaml.xml.ConfigurationException;

import javax.servlet.*;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Properties;

/**
 * Created with IntelliJ IDEA.
 * User: seth.yang
 * Date: 13-8-23
 * Time: 下午5:53
 */
public class SamlListener implements ServletContextListener {
    private Log logger = LogFactory.getLog (SamlListener.class);

    @Override
    public void contextInitialized (ServletContextEvent e) {
        try {
            if (logger.isDebugEnabled ())
                logger.debug ("loading open saml engine ... ");
            DefaultBootstrap.bootstrap ();
            if (logger.isDebugEnabled ())
                logger.debug ("open saml engine booted");
        } catch (ConfigurationException ex) {
            throw new RuntimeException (ex);
        }

        ServletContext context = e.getServletContext ();

        if (logger.isDebugEnabled ())
            logger.debug ("checking configurations ... ");
        String path = context.getInitParameter ("sso.saml.config");
        if (StringUtil.isEmpty (path)) {
            String message =
                    "Can't find init parameter: org.dreamwork.sso.saml.config\n" +
                            "\tPlease add config file into /WEB-INF/web.xml as servlet's init-param.";
            throw new RuntimeException (message);
        }

        try {
            if (logger.isDebugEnabled ())
                logger.debug ("find configuration at: " + path);
            InputStream in = context.getResourceAsStream (path);
            Properties props = new Properties ();
            try {
                props.load (in);
                if (logger.isDebugEnabled ()) {
                    StringWriter writer = new StringWriter ();
                    PrintWriter out = new PrintWriter (writer, true);
                    props.list (out);
                    out.flush ();
                    logger.debug (writer.getBuffer ());
                    logger.debug ("configurations save as: " + SamlKeys.CONFIG_CONTEXT_KEY);
                }
                context.setAttribute (SamlKeys.CONFIG_CONTEXT_KEY, props);
            } finally {
                if (in != null) in.close ();
            }
        } catch (Exception ex) {
            throw new RuntimeException (ex);
        }

        if (logger.isDebugEnabled ())
            logger.debug ("trying to find KeyFetcherFactory");
        KeyFetcherFactory factory = KeyFetcherFactory.newInstance ();
        if (logger.isDebugEnabled ()) {
            logger.debug ("Key Fetcher Factory found: " + factory.getClass ());
            logger.debug ("trying to find key fetcher ...");
        }
        IKeyFetcher fetcher = factory.getFetcher ();
        if (logger.isDebugEnabled ()) {
            logger.debug ("Key Fetcher found: " + fetcher.getClass ());
            logger.debug ("Key Fetcher save as : " + SamlKeys.KEY_FETCHER_CONTEXT_KEY);
        }
        context.setAttribute (SamlKeys.KEY_FETCHER_CONTEXT_KEY, fetcher);
    }

    @Override
    public void contextDestroyed (ServletContextEvent e) {
        ServletContext context = e.getServletContext ();
        context.removeAttribute (SamlKeys.CONFIG_CONTEXT_KEY);
        context.removeAttribute (SamlKeys.KEY_FETCHER_CONTEXT_KEY);
    }
}